#include "SockStream.h"
#include "SockAcceptor.h"

#include <errno.h>
#include <stdio.h>
#include <sys/epoll.h>
#include <iostream>

InetAddr local_addr (9999);

SockStream peer;
SockAcceptor acceptor;
char buff[512] = {0};
int ep_fd = -1;
void *opt_epoll (void *arg)
{
#if 0
    while (1)
    {
	int len = peer.recv (buff, 512);
	if (len <= 0)
	    break;
	std::cout << buff << std::endl;
	peer.send (buff, len);
    }
#elif 0
    int ret = Socket::handle_read_ready (peer.handle (), 2*1000);
    if (ret <= 0)
    {
	perror ("select");
	std::cout << "timeout of error, ret = " << ret << std::endl;
    }
    peer.recv (buff, 512);
    std::cout << buff << std::endl;
    std::cout << "start to sleep, wait client close\n";
    sleep (5);
    ret = Socket::handle_read_ready (peer.handle (), 2*1000);
    if (ret <= 0)
    {
	perror ("select2");
	std::cout << "timeout of error 2, ret = " << ret << std::endl;
    }
    int len = peer.recv (buff, 512);
    if (len == 0)
    {
	std::cout << "client close\n";
    }
#   else
    int ret = epoll_wait (ep_fd, evs, 20, -1);
    if (ret <= 0)
    {
	perror ("select");
	std::cout << "timeout of error, ret = " << ret << std::endl;
    }
    std::cout << "catch an input event\n";
    peer.recv (buff, 512);
    std::cout << buff << std::endl;
    std::cout << "start to sleep, wait client close\n";
    sleep(8);
#endif
    peer.close ();
}
int main ()
{
    if (acceptor.open (local_addr) != 0)
    {
	std::cout << errno << std::endl;
	perror ("open");
	return 0;
    }
    InetAddr remote_addr;
    if (acceptor.accept (peer, &remote_addr) != 0)
    {
	std::cout << errno << std::endl;
	perror ("accept");
	return 0;
    }
    ep_fd = epoll_create (20);
    struct epoll_event ep, evs[20];
    ep.events  = EPOLLIN | EPOLLET;
    ep.data.fd = peer.handle ();
    epoll_ctl (ep_fd, EPOLL_CTL_ADD, peer.handle (), &ep);

    pthread_t pid;
    pthread_create (&pid, NULL, opt_epoll, NULL);
    sleep (5);

    struct epoll_event ep;
    ep.events  = EPOLLIN | EPOLLET;
    ep.data.fd = 0;
    epoll_ctl (ep_fd, EPOLL_CTL_ADD, peer.handle (), &ep);
    pthread_join (pid, NULL);
    return 0;
}
